{
 "cells": [
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "# 6 图像识别与卷积神经网络\n",
    "在第5章中，通过MNIST 数据集验证了第4章介绍的神经网络设计与优化的方法，从实验的结果可以看出，**神经网络的结构会对神经网络的准确率产生巨大的影响**。本章将介绍一个非常常用的神经网络结构——**卷积神经网络（Convolutional Neural Network, CNN）**。\n",
    "\n",
    "卷积神经网络的应用非常广泛，在自然语言处理、医药发现、灾难气候发现甚至围棋人工智能程序中都有应用。本章将主要通过卷积神经网络在图像识别上的应用来讲解卷积神经网络的基本原理以及如何使用TensorFlow实现卷积神经网络。\n",
    "\n",
    "## 6.1 图像识别问题简介及经典数据集\n",
    "视觉是人类认识世界非常重要的一种知觉。对于人类来说，通过视觉来识别手写体数字、识别图片中的物体或者找出图片中人脸的轮廓都是非常简单的任务，然而对于计算机而言，让计算机识别图片中的内容就不是一件容易的事情了。\n",
    "\n",
    "**图像识别问题希望借助计算机程序来处理、分析和理解图片中的内容，使得计算机可以从图片中自动识别各种不同模式的目标和对象，**比如在第5章中介绍的MNIST数据集就是通过计算机来识别图片中的手写体数字。图像识别问题作为人工智能的一个重要领域，在最近几年己经取得了很多突破性的进展。\n",
    "\n",
    "**1. MNIST**\n",
    "\n",
    "第5.1节已经介绍过，MNIST数据集是NIST数据集的一个子集，它包含了60000张图片作为训练数据，10000张图片作为测试数据。在MNIST数据集中的每张图片都代表了0~9中的一个数字，图片大小是**28\\*28，黑白图片**。更详细介绍可以参考这个[网站](http://yann.lecun.com/exdb/mnist)。\n",
    "<p align='center'>\n",
    "    <img src=images/图6.1.JPG>\n",
    "</p>\n",
    "\n",
    "上图显示了图像识别的主流技术在MNIST数据集上的错误率随着年份的发展趋势图，最下方的虚线表示的是人工标注的错误率，其他不同的线段表示了不同算法的错误率。可以看到相比其他算法，CNN可以得到更低的错误率，而且CNN达到的错误率接近人工标注的错误率了。在MNIST数据集的一万个测试数据上，最好的深度学习算法只会比人工识别多错一张图片。\n",
    "\n",
    "**2. CIFAR-10**\n",
    "\n",
    "MNIST手写识别数据集是一个相对简单的数据集，在其他更加复杂的图像识别数据集上，CNN有着更加突出的表现。CIFAR数据集就是一个影响力很大的图像分类数据集。CIFAR数据集分为了CIFAR-10和CIFAR-100两个问题，它们都是图像词典项目（Visual Dictionary）中800万张图片的一个子集。CIFAR数据集中的图片为**32×32的彩色图片**，这些图片是由Alex Krizhevsky教授、Vinod Nair博士和Geoffrey Hinton教授整理的。\n",
    "<p align='center'>\n",
    "    <img src=images/图6.2.JPG>\n",
    "</p>\n",
    "\n",
    "CIFAR-10问题收集了来自10个不同种类的60000张图片。上图显示了CIFAR-10数据集中的每一个种类中的一些样例图片以及这些种类的类别名称，图6-2的右侧给出CIFAR-10中一张飞机的图像。因为图像的像素仅为32×32，所以放大之后图片是比较模糊的，但隐约还是可以看出飞机的轮廓。[CIFAR官网](https://www.cs.toronto.edu/~kriz/cifar.html)提供了不同格式的CIFAR数据集下载，具体的数据格式这里不再赘述。\n",
    "<p align='center'>\n",
    "    <img src=images/图6.3.JPG>\n",
    "</p>\n",
    "\n",
    "和MNIST数据集类似，CIFAR-10中的图片大小都是固定的且每一张图片中仅包含一个种类的实体。**但和MNIST相比CIFAR数据集最大的区别在于图片由黑白变成的彩色，且分类的难度也相对更高**。在CIFAR-10数据集上，人工标注的正确率大概为94%，这比MNIST数据集上的人工表现要低很多。图6.3给出了MNIST和CIFAR-10数据集中比较难以分类的图片样例。在图6.3左侧的4 张图片给出了CIFAR-10数据集中比较难分类的图片，直接从图片上看，人类也很难判断图片上实体的类别。图6.3右侧的4张图片给出了MNIST数据集中难度较高的图片。在这些难度高的图片上，人类还是可以有一个比较准确的猜测。目前在CIFAR-10数据集上最好的图像识别算法正确率为95.59%，达到这个正确率的算法同样使用了卷积神经网络。\n",
    "\n",
    "**3.ImageNet**\n",
    "\n",
    "无论是MNIST数据集还是CIFAR数据集，相比真实环境下的图像识别问题，有两个最大的问题。第一，**现实生活中的图片分辨率要远高于32×32，而且图像的分辨率也不会是同定的。第二，现实生活中的物体类别很多，无论是10种还是100种都远远不够，而且一张图片中不会儿出现一个种类的物体**。为了更加贴近真实环境下的图像识别问题，由斯坦福大学（Stanford University）的李飞飞（Feifei Li）教授带头整理的ImageNet很大程度地解决了这两个问题。\n",
    "\n",
    "ImageNet是一个基于WordNet的大型图像数据库。在ImageNet中，将**近1500万图片被关联到了WordNet的大约20000个名词同义词集上**。目前每一个与ImageNet相关的WordNet同义词集都代表了现实世界中的一个实体，可以被认为是分类问题中的一个类别。ImageNet中的图片都是从互联网上爬取下来的，并且通过亚马逊的人工标注服务（Amazon Mechanical Turk）将图片分类到WordNet的同义词集上。在ImageNet的图片中，一张图片中可能出现多个同义词集所代表的实体。\n",
    "<p align='center'>\n",
    "    <img src=images/图6.4.JPG>\n",
    "</p>\n",
    "\n",
    "上图展示了ImageNet中的一张图片，在这张图片上用几个矩形框出了不同实体的轮廓。在物体识别问题中，一般将用于框出实体的矩形称为bounding box。在图6-4中总共可以找到4个实体，其中有两把椅子、一个人和一条狗。类似图6-4中所示，ImageNet的部分图片中的实体轮廓也被标注了出来，以用于更加精确的图像识别。\n",
    "\n",
    "ImageNet每年都举办图像识别相关的竞赛（ImageNet Large Scale Visual Recognition Challenge, ILSVRC），而且每年的竞赛都会有一些不同的问题，这些问题基本涵盖了图像识别的主要研究方向。ImageNet的[官网](http://www.image-net.org/challenges/LSVRC) 列出了历届ILSVRC竞赛的题目和数据集。不同年份的ImageNet比赛提供了不同的数据集，*本书将着重介绍使用得最多的ILSVRC2012图像分类数据集。*\n",
    "\n",
    "ILSVRC2012图像分类数据集的任务和CIFAR数据集是基本一致的，也是识别图像中的主要物体。ILSVRC2012图像分类数据集包含了**来自1000个类别的120万张图片，其中每张图片属于且只属于一个类别**。因为ILSVRC2012图像分类数据集中的图片是直接从互联网上爬取得到的，所以图片的大小从几千字节到几百万字节不等。\n",
    "<p align='center'>\n",
    "    <img src=images/图6.5.JPG>\n",
    "</p>\n",
    "\n",
    "上图给出了不同算法在ImageNet图像分类数据集上的top-5正确率（top-N正确率指的是图像识别算法给出前N个答案中有一个是正确的概率，在图像分类问题上，很多学术论文都将前N个答案的正确率作为比较的方法，其中N的取值一般为3或5）。从图6.5中可以看出，在更加复杂的ImageNet问题上，基于CNN的图像识别算法可以远远超过人类的表现。在图6.5的左侧对比了传统算法与深度学习算法的正确率。从图中可以看出，**深度学习，特别是卷积神经网络，给图像识别问题带来了质的飞跃。2013年之后，基本上所有的研究都集中到了深度学习算法上。**"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "## 6.2 卷积神经网络简介\n",
    "前面章节所介绍的神经网络每两层之间所有节点都是有边连接的，称之为“全连接神经网络”。下图是全连接神经网络和CNN的结构对比图：\n",
    "<p align='center'>\n",
    "    <img src=images/图6.6.JPG>\n",
    "</p>\n",
    "\n",
    "**1. 全连接神经网络和CNN异同：**\n",
    "\n",
    "相同点：\n",
    "- 结构相似，二者都是通过一层层的节点组织起来；\n",
    "- 输入输出及训练流程也基本一致，以图像分类为例，输入层都是一维的像素点。\n",
    "\n",
    "不同点：\n",
    "- 唯一区别在于神经网络的相邻两层的连接方式，前者相邻两层所有节点都是有边连接，而CNN相邻两层只有部分节点相连。\n",
    "\n",
    "也因此，**使用全连接网络处理图像问题的最大问题在于全连接层的参数太多**。对于MNIST数据，每一张图片的大小是28×28×1，其中28×28为图片的大小×1表示图像是黑白的，只有一个色彩通道。假设第一层隐藏层的节点数为500个，那么一个全链接层的州经网络将有28×28×500+500=392500个参数。当图片更大时，比如在CIFAR-10数据集中，图片的大小为32×32×3，其中32×32表示图片的大小，×3表示图片是通过红绿蓝三个色彩通道(channel）表示的。这样输入层就有3072 个节点，如果第一层全连接层仍然是500个节点，那么这一层全链接神经网络将有3072×500+500，约150万个参数。**参数增多除了导致计算速度减慢，还很容易导致过拟合问题**。所以需要一个更合理的神经网络结构来有效地减少神经网络中参数个数，卷积神经网络就可以达到这个目的。\n",
    "\n",
    "**2. CNN基本结构**\n",
    "<p align='center'>\n",
    "    <img src=images/图6.7.JPG>\n",
    "</p>\n",
    "\n",
    "在卷积神经网络的前几层中，每一层的节点都被组织成一个三维矩阵。比如处理CIFAR-10数据集中的图片时，可以将输入层组织成一个32×32×3的三维矩阵。图6.7中虚线部分展示了卷积神经网络的一个连接示意图，从图中可以看出卷积神经网络中前几层中每一个节点只和上一层中部分的节点相连。卷积神经网络的具体连接方式将在6.3节中介绍。一个卷积神经网络主要由以下5 种结构组成：\n",
    "\n",
    "- **输入层，整个神经网络的输入，在处理图像的卷积神经网络中，它一般代表了一张图片的像素矩阵**。比如在图6.7中，最左侧的三维矩阵就可以代表一张图片。其中三维矩阵的长和宽代表了图像的大小，而三维矩阵的深度代表了图像的色彩通道。比如黑白图片的深度为l，而在RGB色彩模式下，图像的深度为3。从输入层开始，卷积神经网络通过不同的神经网络结构将上一层的三维矩阵转化为下一层的三维矩阵，直到最后的全连接层。\n",
    "- **卷积层，是一个卷积神经网络中最为重要的部分**。和传统全连接层不同，卷积层中每一个节点的输入只是上一层神经网络的一小块，这个小块常用的大小有3×3或者5×5。卷积层试图将神经网络中的每一小块进行更加深入地分析从而得到抽象程度更高的特征。一般来说，通过卷积层处理过的节点矩阵会变得更深，所以在图6.7中可以看到经过卷积层之后的节点矩阵的深度会增加。\n",
    "- **池化层（Pooling），不会改变三维矩阵的深度，但是它可以缩小矩阵的大小**。池化操作可以认为是将一张分辨率较高的图片转化为分辨率较低的图片。通过池化层，可以进一步缩小最后全连接层中节点的个数，从而达到减少整个神经网络中参数的目的。\n",
    "- **全连接层**。如图6.7所示，在经过多轮卷积层和池化层的处理之后，在卷积神经网络的最后一般会是由1到2个全连接层来给出最后的分类结果。经过几轮卷积层和池化层的处理之后，可以认为图像中的信息已经被抽象成了信息含量更高的特征。我们可以将卷积层和池化层看成自动图像特征提取的过程。在特征提取完成之后，仍然需要使用全连接层来完成分类任务。\n",
    "- **Softmax层，主要用于分类问题，可以得到当前样例属于不同种类的概率分布情况。**\n",
    "\n",
    "在卷积神经网络中使用到的输入层、全连接层和Softmax层在第4章中都有过详细的介绍，这里不再赘述。在下面的6.3节中将详细介绍卷积神经网络中特殊的两个网络结构一一卷积层和池化层。"
   ]
  }
 ],
 "metadata": {
  "kernelspec": {
   "display_name": "Python 3",
   "language": "python",
   "name": "python3"
  },
  "language_info": {
   "codemirror_mode": {
    "name": "ipython",
    "version": 3
   },
   "file_extension": ".py",
   "mimetype": "text/x-python",
   "name": "python",
   "nbconvert_exporter": "python",
   "pygments_lexer": "ipython3",
   "version": "3.6.4"
  }
 },
 "nbformat": 4,
 "nbformat_minor": 2
}
